package com.example.demo.controller;

import java.io.BufferedInputStream;  
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.task.Attachment;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.example.demo.dao.PlatId_ProcessInstanceIdMapper;
import com.example.demo.dao.PlatMapper;
import com.example.demo.dao.ProjectId_processInstanceIdMapper;
import com.example.demo.dao.ProjectMapper;
import com.example.demo.dao.Project_detailsMapper;
import com.example.demo.domain.Plat;
import com.example.demo.domain.PlatId_ProcessInstanceId;
import com.example.demo.domain.Project;
import com.example.demo.domain.ProjectId_processInstanceId;
import com.example.demo.domain.Project_details;
import com.example.demo.services.ActivitiService;
import com.example.demo.services.PlatService;
import com.example.demo.services.ProjectService;
import com.example.demo.util.FileUtils;
import com.example.demo.util.MergeFileUtils;
import com.example.demo.util.Util;

@RestController
@RequestMapping("/upLoadFile")
public class UpLoadFileController {
	
	private static Logger logger = Logger.getLogger(ProjectController.class);
	
	@Autowired
	private Project_detailsMapper project_detailsMapper;
	
	@Autowired
	private ProjectMapper projectMapper;
	
	@Autowired
	private ProjectId_processInstanceIdMapper projectId_processInstanceIdMapper;
	
	@Autowired
	private ActivitiService activitiService;
	
	@Autowired
	private PlatMapper platMapper;
	
	@Autowired
	private PlatId_ProcessInstanceIdMapper platId_ProcessInstanceIdMapper;
	
	@Autowired
	private PlatService platService;
	
	@Autowired
	private ProjectService projectService;
	
	/**
	 *  by dsh
	 * *保存上传的标定数据文件
	 * @throws FileNotFoundException 
	 * */
	@RequestMapping("/uploadCalibrationDataFile")
	@ResponseBody
	public Object upload(MultipartFile file,HttpServletRequest servletRequest,String processInstanceId,String taskId) throws FileNotFoundException{
		Map<String, Object> obj = new HashMap<String, Object>();
		Project_details processInstance = project_detailsMapper.queryProject(processInstanceId);//流程实例
		
		String str = "";
		if(processInstance.getType()==1) {
			PlatId_ProcessInstanceId platId_ProcessInstanceId = platId_ProcessInstanceIdMapper.selectByProcessInstanceId(processInstanceId);
			Plat plat = platMapper.selectByPrimaryKey(Integer.valueOf(platId_ProcessInstanceId.getPlatid()));
			str = plat.getName();
		}else {
			ProjectId_processInstanceId projectId_processInstanceId = projectId_processInstanceIdMapper.selectByPrimaryKey(processInstanceId);
			Project project = projectMapper.selectByPrimaryKey(projectId_processInstanceId.getProjectid());
			str = project.getProjectName();
		}
		
		//上传文件路径 
        String path = "D:/UploadFile"+ "/" + str + "/" + processInstance.getName() + "/" + taskId;
        //上传文件名         
        String name = file.getOriginalFilename();//上传文件的真实名称
        List<Attachment> attachments = activitiService.findTaskAttachmentsTable(taskId);
        //判断是否存在相同名称的文件，存在则删除
        for(Attachment attachment : attachments) {
        	if(name.equals(attachment.getName())) {
        		activitiService.deleteAttachmentById(attachment.getId());
        		FileUtils.deleteFile(attachment.getUrl());
        	}
        }
        
        String suffixName = "";
        if(name.indexOf(".") != -1) {
        	suffixName = name.substring(name.lastIndexOf("."));//获取后缀名
        }
        String hash = Integer.toHexString(new Random().nextInt());//自定义随机数（字母+数字）作为文件名
        String fileName = hash + suffixName;        
        File filepath = new File(path, fileName); 
        //判断路径是否存在，没有就创建一个 
        if (!filepath.getParentFile().exists()) { 
            filepath.getParentFile().mkdirs(); 
        } 
        //将上传文件保存到一个目标文档中 
        File tempFile = new File(path + File.separator + fileName);
    	try {
			file.transferTo(tempFile);
//			new Thread(){
//				public void run(){
//					DocConverterUtil.word2pdf(tempFile.getPath());
//				}
//			}.start();
			obj.put("filePath", tempFile.getPath().replaceAll("\\\\", "/"));
			obj.put("fileName", name);
			obj.put(Util.RESULT, Util.RESULT_RC_SUCCESS);
			obj.put(Util.MESSAGE, "保存文件成功");
		} catch (IllegalStateException | IOException e) {
			tempFile.delete();
			// TODO Auto-generated catch block
			obj.put(Util.RESULT, Util.RESULT_RC_EXCEPTION);
			obj.put(Util.MESSAGE, "保存文件失败");
			logger.error(e.getStackTrace());
		}	 
		return obj;
	}
	
	/**
	 *  by dsh
	 * *验证是否存在相同文件名
	 * */
	@RequestMapping("/validateFileExist")
	public String validateFileExist(String fileName,HttpServletRequest servletRequest,String taskId){
		String result = "0";//0代表不存在相同文件，1代表存在
		List<Attachment> attachments = activitiService.findTaskAttachmentsTable(taskId);
		for(Attachment attachment: attachments) {
			if(attachment.getName().equals(fileName)) {
				result = "1";
				break;
			}
		}
        return result;
	}
	
	/**
	 *  by dsh
	 * *  下载多个文件并打包成压缩包zip
	 * */
	@RequestMapping("/downLoadMutilFilesToZip")
	public void  downLoadMutilFilesToZip(HttpServletRequest servletRequest, HttpServletResponse response, String[] names , String[] paths){
		 //存放--服务器上zip文件的目录
        String directory = "D:\\repository\\"+"dsada";
        File directoryFile=new File(directory);
        if(!directoryFile.isDirectory() && !directoryFile.exists()){
            directoryFile.mkdirs();
        }
        //设置最终输出zip文件的目录+文件名
        SimpleDateFormat formatter  = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
        String zipFileName = formatter.format(new Date())+".zip";
        String strZipPath = directory+"\\"+zipFileName;
 
        ZipOutputStream zipStream = null;
        FileInputStream zipSource = null;
        BufferedInputStream bufferStream = null;
        File zipFile = new File(strZipPath);
        try{
            //构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            for (int i = 0; i<paths.length ;i++){
                //解码获取真实路径与文件名
                String realFileName = java.net.URLDecoder.decode(names[i],"UTF-8");
                String realFilePath = java.net.URLDecoder.decode(paths[i],"UTF-8");
                File file = new File(realFilePath);
                //TODO:未对文件不存在时进行操作，后期优化。
                if(file.exists())
                {
                    zipSource = new FileInputStream(file);//将需要压缩的文件格式化为输入流
                    /**
                     * 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样这里的name就是文件名,
                     * 文件名和之前的重复就会导致文件被覆盖
                     */
                    ZipEntry zipEntry = new ZipEntry(realFileName);//在压缩目录中文件的名字
                    zipStream.putNextEntry(zipEntry);//定位该压缩条目位置，开始写入文件到压缩包中
                    bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
                    int read = 0;
                    byte[] buf = new byte[1024 * 10];
                    while((read = bufferStream.read(buf, 0, 1024 * 10)) != -1)
                    {
                        zipStream.write(buf, 0, read);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if(null != bufferStream) bufferStream.close();
                if(null != zipStream){
                    zipStream.flush();
                    zipStream.close();
                }
                if(null != zipSource) zipSource.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //判断系统压缩文件是否存在：true-把该压缩文件通过流输出给客户端后删除该压缩文件  false-未处理
        if(zipFile.exists()){
        	downLoadFile(response,zipFileName,strZipPath);
            zipFile.delete();
        }

	}
	
	@RequestMapping("/downLoadFile")
     public void downLoadFile(HttpServletResponse response,String filename,String path ){
        if (filename != null) {
            FileInputStream is = null;
            BufferedInputStream bs = null;
            OutputStream os = null;
            try {
                File file = new File(path);
                if (file.exists()) {
                    //设置Headers
                    response.setHeader("Content-Type","application/octet-stream");
                    //设置下载的文件的名称-该方式已解决中文乱码问题
                    response.setHeader("Content-Disposition","attachment;filename=" +  new String( filename.getBytes("gb2312"), "ISO8859-1" ));
                    is = new FileInputStream(file);
                    bs =new BufferedInputStream(is);
                    os = response.getOutputStream();
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while((len = bs.read(buffer)) != -1){
                        os.write(buffer,0,len);
                    }
                }else{
                    //String error = Base64Util.encode("下载的文件资源不存在");
                    //response.sendRedirect("/imgUpload/imgList?error="+error);
                }
            }catch(IOException ex){
                ex.printStackTrace();
            }finally {
                try{
                    if(is != null){
                        is.close();
                    }
                    if( bs != null ){
                        bs.close();
                    }
                    if( os != null){
                        os.flush();
                        os.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
	
	
	@RequestMapping("/officeToPdf")
    public void showAttachment(HttpServletResponse response,String filename,String url ){
	}
	
	
	/**
	 *  by dsh
	 * *保存上传的标定数据文件
	 * @throws FileNotFoundException 
	 * */
	@RequestMapping("/uploadGlobalFile")
	@ResponseBody
	public Object uploadGlobalFile(MultipartFile file,HttpServletRequest servletRequest,String processInstanceId,String taskId) throws FileNotFoundException{
		Map<String, Object> obj = new HashMap<String, Object>();
		String processInstanceFileId = servletRequest.getParameter("processInstanceFileId") == null ? "" : servletRequest.getParameter("processInstanceFileId");
		Project_details processInstance = project_detailsMapper.queryProject(processInstanceId);//流程实例
						
		String str = "";//项目或者平台名称
		if(processInstance.getType()==1) {
			PlatId_ProcessInstanceId platId_ProcessInstanceId = platId_ProcessInstanceIdMapper.selectByProcessInstanceId(processInstanceId);
			Plat plat = platMapper.selectByPrimaryKey(Integer.valueOf(platId_ProcessInstanceId.getPlatid()));
			str = plat.getName();
		}else {
			ProjectId_processInstanceId projectId_processInstanceId = projectId_processInstanceIdMapper.selectByPrimaryKey(processInstanceId);
			Project project = projectMapper.selectByPrimaryKey(projectId_processInstanceId.getProjectid());
			str = project.getProjectName();
		}
		//上传文件路径 
        String path = "d:/UploadFile"+ "/" + str + "/" + processInstance.getName();
        //上传文件名         
        String name = file.getOriginalFilename();//上传文件的真实名称
        String suffixName = "";
        if(name.indexOf(".") != -1) {
        	suffixName = name.substring(name.lastIndexOf("."));//获取后缀名
        }
        String hash = Integer.toHexString(new Random().nextInt());//自定义随机数（字母+数字）作为文件名
        String fileName = hash + suffixName;        
        File filepath = new File(path, fileName); 
        //判断路径是否存在，没有就创建一个 
        if (!filepath.getParentFile().exists()) { 
            filepath.getParentFile().mkdirs(); 
        } 
        //将上传文件保存到一个目标文档中 
        File tempFile = new File(path + File.separator + fileName);
    	try {
			file.transferTo(tempFile);		
			String version = "";
			obj.put("fileType", "");
			if(suffixName.equals(".s19") || suffixName.equals(".S19") || suffixName.equals(".mot") || suffixName.equals(".MOT")) {
				obj.put("fileType", "s19");
				version = MergeFileUtils.findFileVersion(processInstance.getType(), tempFile);;
//				try {
//					version = MergeFileUtils.findFileVersion(processInstance.getType(), tempFile);	
//					if(version.equals("")) {
//						tempFile.delete();
//						obj.put(Util.RESULT, 2);
//						obj.put(Util.MESSAGE, "读取文件版本，16进制转换成ASCII码时16进制数字超出转换范围");
//						return obj;
//					}
//				}catch (Exception e) {
//					tempFile.delete();
//					logger.error(e);
//					obj.put(Util.RESULT, 2);
//					obj.put(Util.MESSAGE, "查找文件版本时出错");
//					return obj;
//				}				
//				if(processInstance.getType() == 1) {
//					int versionInt = Integer.valueOf(version.substring(2,7));
//					Plat plat = platMapper.selectByProcessInstanceId(processInstanceId);
//					List<Map<String, Object>> list =  platService.selectProcessInstanceByPlatId(plat.getId()+"");
//					for(Map<String, Object> map: list) {
//						String hisVersion = (String) map.get("version");
//						if(hisVersion!=null&&!hisVersion.equals("")&&hisVersion.length() == 8) {
//							int histVersionInt = Integer.valueOf(hisVersion.substring(2,7));
//							if(histVersionInt >= versionInt) {
//								tempFile.delete();
//								obj.put(Util.RESULT, 2);
//								obj.put(Util.MESSAGE, version + ",此版本小于或等于平台已存在程序版本");
//								return obj;
//							}
//						}
//					}
//				}else {
//					int versionInt = Integer.valueOf(version.substring(8,10));
//					int projectId = projectService.findProjectIdPid(processInstanceId);
//					List<Map<String, Object>> list = projectService.findProcessInstanceByprojectId(projectId+"", "2");//2代表标定数据
//					for(Map<String, Object> map: list) {
//						String hisVersion = (String) map.get("version");
//						if(hisVersion!=null&&!hisVersion.equals("")&&hisVersion.length() == 10) {
//							int histVersionInt = Integer.valueOf(hisVersion.substring(8,10));
//							if(histVersionInt >= versionInt) {
//								tempFile.delete();
//								obj.put(Util.RESULT, 2);
//								obj.put(Util.MESSAGE, version + ",此版本小于或等于项目已存在版本");
//								return obj;
//							}
//						}
//					}
//				}
//				processInstance.setVersion(version);
//				project_detailsMapper.updateByPrimaryKey(processInstance);
			}
            activitiService.addGlobalFIle(processInstanceId, taskId,tempFile.getPath().replaceAll("\\\\", "/"),name,processInstanceFileId);
			obj.put(Util.RESULT, Util.RESULT_RC_SUCCESS);
			obj.put(Util.MESSAGE, "上传文件成功，文件版本为"+ version);
		} catch (IllegalStateException | IOException e) {
			tempFile.delete();
			// TODO Auto-generated catch block
			obj.put(Util.RESULT, Util.RESULT_RC_EXCEPTION);
			obj.put(Util.MESSAGE, "保存文件失败");
			logger.error(e.getStackTrace());
		}	 
		return obj;
	}
	
	/**
	 * 	合并程序和数据文件
	 * @author dsh
	 * @param 
	 * @return List<Attachment>
	 */
	@RequestMapping(value = "/mergeFile")
	public String  mergeFile(HttpServletRequest servletRequest, String processInstanceId,String taskId, String programFilePath, String dataFilePath,String version) throws Exception {
		String result = "fail";
		try {		
			Project_details processInstance = project_detailsMapper.queryProject(processInstanceId);//流程实例
            Map<String, String > map =  MergeFileUtils.mergeFile(programFilePath, dataFilePath, processInstance.getName());
            processInstance.setVersion(version);
            project_detailsMapper.updateByPrimaryKey(processInstance);
            activitiService.addGlobalFIle(processInstanceId, taskId,map.get("path").replaceAll("\\\\", "/"),map.get("name"),"");//只能直接生成，不能更新所以最后一个参数为空
            result = "success";
		} catch (Exception e) {
			logger.error("=============[ActivitiController[addAttachments[标定数据和程序绑定]]]==========", e);
		}
		return result;
	}

}
